package chapt04.sphereworld;
// SphereWorld.java
// OpenGL SuperBible
// Demonstrates an immersive 3D environment using actors and a camera.
// Program by Richard S. Wright Jr.

import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;

import com.jogamp.opengl.util.gl2.GLUT;

import java.util.Random;

import shared.*;

public class SphereWorld
{
	static GLU glu = new GLU();
	static GLUT glut = new GLUT();
	
	static int NUM_SPHERES = 50;
	static GLFrame spheres[] = new GLFrame[NUM_SPHERES];
	static GLFrame frameCamera = new GLFrame();
	
	static float yRot = 0.0f; // Rotation angle for animation
	
	//////////////////////////////////////////////////////////////////
	// This function does any needed initialization on the rendering
	// context. 
	protected static void setup(GL2 gl2, int width, int height)
	{
		int iSphere;
		Random random = new Random();
		
		// Bluish background
		gl2.glClearColor(0.0f, 0.0f, 0.5f, 1.0f);
		
		// Draw everything as wire frame
		gl2.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
		
		// Randomly place the sphere inhabitants
		for(iSphere = 0; iSphere < NUM_SPHERES; iSphere++)
		{
			// Pick a random location between -20 and 20 at .1 increments
			float x = ((float)random.nextInt(400) - 200) * 0.1f;
			float z = ((float)random.nextInt(400) - 200) * 0.1f;
			spheres[iSphere] = new GLFrame();
			spheres[iSphere].setOrigin(x, 0.0f, z);
		}
	}

	///////////////////////////////////////////////////////////
	// Draw a gridded ground
	static void drawGround(GL2 gl2)
	{
		float fExtent = 20.0f;
		float fStep = 1.0f;
		float y = -0.4f;
		float iLine;
		
		gl2.glBegin(GL2.GL_LINES);
			for(iLine = -fExtent; iLine <= fExtent; iLine += fStep)
			{
				gl2.glVertex3f(iLine, y, fExtent); // Draw Z lines
				gl2.glVertex3f(iLine, y, -fExtent);
				
				gl2.glVertex3f(fExtent, y, iLine);
				gl2.glVertex3f(-fExtent, y, iLine);
			}
		gl2.glEnd();
	}
	
	// Called to draw scene
	protected static void render(GL2 gl2, int w, int h)
	{
		float fAspect;
		
		// Prevent a divide by zero, when window is too short
		// (you can't make a window of zero width).
		if(h == 0)
			h = 1;
		
		gl2.glViewport(0, 0, w, h);
		
		fAspect = (float)w / (float)h;
		
		// Reset the coordinate system before modifying
		gl2.glMatrixMode(GL2.GL_PROJECTION);
		gl2.glLoadIdentity();
		
		// Set the clipping volume
		glu.gluPerspective(35.0f, fAspect, 1.0f, 50.0f);
		
		gl2.glMatrixMode(GL2.GL_MODELVIEW);
		gl2.glLoadIdentity();
		
		int i;
		yRot += 0.5f;
		
		// Clear the window with current clearing color
		gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
		
		gl2.glPushMatrix();
			frameCamera.applyCameraTransform(gl2);
			
			// Draw the ground
			drawGround(gl2);
			
			// Draw the randomly located spheres
			for(i = 0; i < NUM_SPHERES; i++)
			{
				gl2.glPushMatrix();
				spheres[i].applyActorTransform(gl2);
				glut.glutSolidSphere(0.1f, 13, 26);
				gl2.glPopMatrix();
			}
			
			gl2.glPushMatrix();
				gl2.glTranslatef(0.0f, 0.0f, -2.5f);
				
				gl2.glPushMatrix();
					gl2.glRotatef(-yRot * 2.0f, 0.0f, 1.0f, 0.0f);
					gl2.glTranslatef(1.0f, 0.0f, 0.0f);
					glut.glutSolidSphere(0.1f, 13, 26);
				gl2.glPopMatrix();
				
				gl2.glRotatef(yRot, 0.0f, 1.0f, 0.0f);
				GLT.drawTorus(gl2, 0.35f, 0.15f, 40, 20);
			gl2.glPopMatrix();
		gl2.glPopMatrix();
			
		// Do the buffer Swap
		gl2.glFlush();
	}
}